home *** CD-ROM | disk | FTP | other *** search
- _ASSEMBLY LANGUAGE PROGRAMMING FOR THE 80X87_
- by Nicholas Wilt
-
- [LISTING ONE]
-
- ; pow.asm: integer power function callable from Borland C++.
- ; Copyright (C) 1991 by Nicholas Wilt. All rights reserved.
-
- .MODEL LARGE,C
-
- .CODE
-
- ; double intpow(double x, unsigned int y);
- ; Returns x^y.
-
- PUBLIC intpow
-
- intpow PROC X:QWORD,Y:WORD
- fld1 ; Load 1 into the 80x87
- mov cx,Y ; Get y
- fld X ; Load x into the 80x87
-
- jcxz Return ; If y already zero, return
-
- TestY: test cx,1 ; Is the LSB of y set?
- jz NextIteration ; Jump if no
- fmul st(1),st ; ret *= x
- NextIteration:
- fmul st,st(0) ; Square x
- shr cx,1 ; y >>= 1
- jnz TestY ; Continue if nonzero
- Return: fstp st ; Pop stack. Return value is
- ; now in ST(0).
- ret
- intpow ENDP
-
- END
-
-
-
- [LISTING TWO]
-
- ; sumarray(), a Borland C++-callable function to sum the values
- ; in an array of floats.
-
- ; Copyright (C) 1991 by Nicholas Wilt. All rights reserved.
-
- .MODEL LARGE,C
-
- .CODE
-
- ; double sumarray(float *arr, int n);
- ; Returns sum of the n elements in arr.
-
- PUBLIC sumarray
-
- sumarray PROC ARR:DWORD,N:WORD
- les bx,ARR ; ES:BX <- pointer to arr
- mov cx,N ; Get number of elements
- fldz ; Load zero
- jcxz LeaveSum ; Leave if count is 0.
- DoSum: fadd dword ptr es:[bx] ; Add value in array to ST(0).
- add bx,4 ; Point to next value in array.
- loop DoSum ; Loop until done.
- LeaveSum: ; Return value in ST(0).
- ret
- sumarray ENDP
-
- END
-
-
-
- [LISTING THREE]
-
- ; quad.asm: integer power function callable from Borland C++.
- ; Copyright (C) 1991 by Nicholas Wilt. All rights reserved.
-
- .MODEL LARGE,C
-
- .CODE
-
- ; int solve_quadratic(double a, double b, double c, double *x1, double *x2);
- ; solve_quadratic takes the coefficients of a quadratic polynomial
- ; and finds the roots of that polynomial. If there are two real
- ; roots, it writes them back to x1 and x2 and returns 1. If the
- ; discriminant b^2-4*a*c is less than 0, the roots are not real
- ; and solve_quadratic returns 0.
- ; The quadratic formula is as follows:
- ; (-b +/- sqrt(b*b-4*a*c)) / 2*a
-
- PUBLIC solve_quadratic
-
- solve_quadratic PROC A:QWORD,B:QWORD,C:QWORD,X1:DWORD,X2:DWORD
- ; Comments show stack contents
- ; separated by | signs
- ; Stack top is at left
- fld A ; a Here, ST(0) contains a.
- fld B ; b | a Now ST(1) has a. Etc.
-
- ; Negate b -- squaring it is sign-independent, and we need b
- ; negated in all the other instances in the formula.
- fchs
-
- fld C ; c | b | a
- fld st(1) ; b | c | b | a
- fmul st,st(0) ; b*b | c | b | a
-
- ; Just plain fxch has an implicit operand of ST(1).
-
- fxch ; c | b*b | b | a
- fadd st,st(0) ; 2*c | b*b | b | a
- fadd st,st(0) ; 4*c | b*b | b | a
- fmul st,st(3) ; 4*a*c | b*b | b | a
- fsubp st(1), st ; b*b-4*a*c | b | a
- ftst ; Compare against 0
-
- ; We've computed b*b-4*a*c. If negative, we return 0.
- ; To do the comparison, we have to store the 80x87 status
- ; word and use sahf to store it into the flags. Once it's
- ; in the flags, we can jump on above or equal (jae) to jump if the
- ; number tested is greater than 0 after the FTST instruction above.
- sub sp,2 ; Quick, allocate a local
- mov bx,sp ; Point BX at it
- fstsw ss:[bx] ; Store the 80x87's status word there
- mov ax,ss:[bx] ; AX <- status word
- add sp,2 ; Deallocate the local
- sahf ; Get SW into flags
- jae ComputeResults ; Jump if positive
- fstp st ; This instruction clears the stack
- fstp st ; we've got three values on the stack
- fstp st ; to clear
- xor ax,ax ; Return 0 - no roots found.
- jmp short LeaveQuadratic
- ComputeResults:
- fsqrt ; Find square root of discriminant
- fxch st(2) ; a | b | sqrt(b*b-4*a*c)
- fadd st,st(0) ; 2*a | b | sqrt(b*b-4*a*c)
- fld st(1) ; b | 2*a | b | sqrt(b*b-4*a*c)
- fadd st,st(3) ; b+sqrt(b*b-4*a*c) | 2*a | b | sq..
- fdiv st,st(1) ; x1 | 2*a | b | sqrt(b*b-4*a*c)
- les bx,X1 ;
- fstp qword ptr es:[bx] ; 2*a | b | sqrt(b*b-4*a*c)
- fxch ; b | 2*a | sqrt(b*b-4*a*c)
- fsubrp st(2),st ; 2*a | -b - sqrt(b*b-4*a*c)
- fdiv ; x2
- les bx,X2 ; Store x2
- fstp qword ptr es:[bx]
- mov ax,1 ; Return 1
- LeaveQuadratic:
- ret ; Return
- solve_quadratic ENDP
-
- END
-